import express from 'express'
import { Response, Request } from "express"

const router = express.Router()

import { success, failure } from '../utils/responses'
import { Article } from "../entities/Article"
import { AppDataSource } from "../config/database"
import { BadRequest, NotFound } from "http-errors"
import { Comment } from "../entities/Comment";
import { Post } from "../entities/Post";
import { AuthRequest } from "../middlewares/user-auth";
import { User } from "../entities/User";
import { FindManyOptions } from "typeorm";

enum commentType {
  ARTICLE = 1,
  POST = 2
}

interface commentAddParam {
  targetId: number // 评论所属文章或帖子的id
  content: string, // 评论内容
  type: commentType // 评论类型
}

/**
 * 查询评论
 */
router.get('/', async function (req: Request, res: Response) {
  try {
    const query = req.query
    const targetId = Number(query.targetId) // 文章或帖子id
    const type = Number(query.type) // 文章或帖子
    console.log('执行了')
    if (isNaN(targetId)) throw new BadRequest("请传入合法的文章或帖子id")
    if (!(type && type in commentType)) throw new BadRequest('请传入合法的类型')

    // 查询评论列表
    const currentPage = Math.abs(Number(query.currentPage)) || 1 // 当前页
    const pageSize = Math.abs(Number(query.pageSize)) || 10 // 每页条数
    const offset = (currentPage - 1) * pageSize // 偏移量

    let typeName: string = ''

    // 检查传过来的文章或帖子id是否存在
    if (type === commentType.ARTICLE) {
      const articleRepository = AppDataSource.getRepository(Article)
      const article = await articleRepository.findOneBy({ id: targetId })
      if (!article) throw new NotFound('没有找到文章')
      typeName = 'article' // 赋值
    } else if (type === commentType.POST) {
      const postRepository = AppDataSource.getRepository(Post)
      const post = await postRepository.findOneBy({ id: targetId })
      if (!post) throw new NotFound('没有找到帖子')
      typeName = 'post' // 赋值
    }

    const findOptions: FindManyOptions = {
      relations: {
        [typeName]: true,
        commenter: true
      },
      where: {
        [typeName]: {
          id: targetId
        }
      },
      order: {
        updatedAt: "DESC"
      },
      skip: offset,
      take: pageSize
    }

    const commentRepository = AppDataSource.getRepository(Comment)
    const [comments, totalCount] = await commentRepository.findAndCount(findOptions)

    // 去除不需要的字段
    const filterComments = comments.map(comment => {
      const { id, content, likeCount, createdAt, updatedAt, commenter } = comment
      return {
        id, content, likeCount, createdAt, updatedAt,
        commenter: {
          id: commenter.id,
          username: commenter.username,
          avatar: commenter.avatar,
          role: commenter.role
        },
        [`${typeName}Id`]: targetId
      }
    })
    success(res, '查询评论列表成功', {
      comments: filterComments,
      pagination: {
        totalPage: Math.ceil(totalCount / pageSize),
        currentPage,
        pageSize,
        totalCount
      }
    })
  } catch (error) {
    failure(res, error)
  }
})

/**
 * 新增评论
 */
router.post('/', async function (req: Request, res: Response) {
  try {
    const { targetId, content, type } = req.body as commentAddParam

    if (!content.trim()) throw new BadRequest('评论内容无效')
    if (!(type && type in commentType)) throw new BadRequest('请传入合法的评论类型')

    // 获取评论者，即当前登录用户
    const id = (req as AuthRequest).id
    const currentUser = await AppDataSource.getRepository(User).findOneBy({ id })
    // 创建新评论
    const newComment = new Comment()
    newComment.content = content
    newComment.commenter = currentUser

    // 检查targetId在不在type上
    if (type === commentType.ARTICLE) {
      const articleRepository = AppDataSource.getRepository(Article)
      const article = await articleRepository.findOneBy({ id: targetId })
      if (!article) throw new NotFound('没有找到文章')
      newComment.article = article // 关联评论所属文章
    } else if (type === commentType.POST) {
      const postRepository = AppDataSource.getRepository(Post)
      const post = await postRepository.findOneBy({ id: targetId })
      if (!post) throw new NotFound('没有找到帖子')
      newComment.post = post // 关联评论所属帖子
    }

    // 存储新评论
    const commentRepository = AppDataSource.getRepository(Comment)
    await commentRepository.save(newComment)

    success(res, '新增评论成功')
  } catch (error) {
    failure(res, error)
  }
})

export default router
